`include "ALU.v"
module EXECUTE(icode, ifun, valC, valA, valB, CC_i, valE, CC_o, Bch);
input [3:0] icode;
input [3:0] ifun;
input [31:0] valC;
input [31:0] valA;
input [31:0] valB;
input [31:0] CC_i;
output reg [31:0] valE;
output reg [31:0] CC_o;
output reg Bch;

reg [31:0] aluA;
reg [31:0] aluB;
reg [3:0] aluOP;

wire [31:0] aluOUT;
wire [2:0] aluFLAGS;


//MODULO da alu no estágio de execute
ALU a(.OP(aluOP), .A(aluA), .B(aluB), .C(aluOUT), .FLAGS(aluFLAGS));


always @(icode or ifun or CC_i) begin
	if(icode == 7) begin
		case(ifun)
			0: begin
				Bch <= 1'b1;
			end
			1: begin
				Bch <= (CC_i[2] ^ CC_i[0]) | CC_i[1];
			end
			2: begin
				Bch <= (CC_i[2] ^ CC_i[0]);
			end
			3: begin
				Bch <= CC_i[1];
			end
			4: begin
				Bch <= ~CC_i[1];
			end
			5: begin
				Bch <= ~(CC_i[2] ^ CC_i[0]);
			end
			6: begin
				Bch <= ~(CC_i[2] ^ CC_i[0]) & ~CC_i[1];
			end
		endcase
	end
end


always @(icode or ifun or valC or valA or valB or aluOUT or aluFLAGS) begin
    case(icode)
		0, 1: begin
			CC_o <= CC_i;	
		end
		2: begin
			aluB <= 32'b0;
			aluA <= valA;
			aluOP <= 4'b0;
			valE <= aluOUT;
			CC_o <= CC_i;
		end
		3: begin
			aluB <= 32'b0;
			aluA <= valC;
			aluOP <= 4'b0;
			valE <= aluOUT;
			CC_o <= CC_i;
		end
		4, 5: begin
			aluB <= valB;
			aluA <= valC;
			aluOP <= 4'b0;
			valE <= aluOUT;
			CC_o <= CC_i;
		end
		6: begin
			aluB <= valB;
			aluA <= valA;
			aluOP <= ifun;
			valE <= aluOUT;
			CC_o <= {aluFLAGS, CC_i[28:0]};
		end
		8, 10: begin
			aluB <= valB;
			aluA <= 32'b100;
			aluOP <= 4'b1;
			valE <= aluOUT;
			CC_o <= CC_i;
		end
		9, 11: begin
			aluB <= valB;
			aluA <= 32'b100;
			aluOP <= 4'b0;
			valE <= aluOUT;
			CC_o <= CC_i;
		end
    endcase
end

endmodule
